本文是针对Windows常见持久控制的第三次说明。
与之前的文章不同,这个操作需要管理员权限。
0x00 前言
在日常中,使用 WMI 都是用于信息的收集,如下:
| 1 | wmic qfe list #获取补丁信息 | 
但其实它的功能还有很多,比如:
| 1 | 防病毒检测 | 
这里就针对持久化进行说明 。
0x01 查询 WMI
WMI 提供了一种非常直观的语法用来查询WMI对象的实例,类和命名空间,即 WQL (类似 SQL的查询语言)。WQL查询通常可以分为以下几类:
- Instance Queries(实例查询):查询WMI对象实例。
- Event Queries(事件查询):等同于在WMI对象创建/修改/删除的时候注册一个消息。
- Meta Queries(元查询):元查询用来获取WMI命名空间和类结构的元信息。
1.1 Instance Queries
这是最常用的WQL查询。基本的格式如下:SELECT [Class property name | *] FROM [CLASS NAME] <WHERE [CONSTRAINT]>
- 下面的查询语句将返回所有可执行文件名中带有 chrome的正在运行的进程:SELECT * FROM Win32_Process WHERE Name LIKE "%chrome%"
1.2 Event Queries
事件查询被用作一种消息机制来监听事件类的触发。通常用来在一个WMI对象实例创建/修改/删除的时候给用户发送一个消息。根据消息类型是 intrinsic(系统自带的)还是 extrinsic(第三方的),查询语句格式不同:
| 1 | SELECT [Class property name | *] FROM [INTRINSIC CLASS NAME] WITHIN [POLLING INTERVAL] <WHERE [CONSTRAINT]> | 
- 用于登陆时都会触发此事件: - 1 - SELECT * FROM __InstanceCreationEvent WITHIN 15 WHERE TargetInstanceISA 'Win32_LogonSession' AND TargetInstance.LogonType=2 
- 每次用户在插入可移除设备时都会触发此事件: - 1 - SELECT * FROM Win32_VolumeChangeEvent Where EventType=2 
- 每次创建 win32 进程时都会触发此事件: - 1 - Select * From __InstanceCreationEvent Where TargetInstance Isa "Win32_Process" 
1.3 Meta Queries
元查询用来查询WMI命名空间和类结构的信息。最常见的用法是用来列举WMI命名空间的类结构。元查询是实例查询的一个子集,但是与对象查询不同的是,我们查询的是类的实例的定义。
- 格式如下: - 1 - SELECT [Class property name | *] FROM [Meta_Class | SYSTEM CLASS NAME] <WHERE [CONSTRAINT]> 
- 下面这个语句会查询所有以 - WIN32开头的WMI的类:- SELECT * FROM Meta_Class WHERE __CLASS LIKE "Win32%"
- 下面这个语句会查询某个命名空间下的所有命名空间:SELECT Name FROM __NAMESPACE
注意,当不显示的指定命名空间时,默认的命名空间为ROOT\CIMV2。
0x02 与WMI交互
Microsoft和一些第三方软件开发者为我们提供了许多能够与WMI交互的工具。
下面是部分工具的一个不完全的列表
| 1 | 1、PowerShell | 
0x03 WMI事件
WMI事件分两类,包括本地事件(运行在本地上下文环境当中的单个进程的事件)和永久性WMI事件订阅。
本地事件有生命周期为进程宿主的周期,而永久性 WMI事件 是存储在WMI库中,以 SYSTEM 权限运行,并且重启后依然存在。
3.1 前置条件
为了能够安装一个永久性的 WMI 事件订阅,必须满足两个条件:
- 一个 __EventFilter查询,它创建一个过滤器,为我们的特定事件选择触发器;
- Event Consumer Class,代表一个事件触发时所执行的操作。
在 Event Consumers(事件处理)中,可用的标准事件处理类:1
2
3
4
5LogFileEventConsumer: 将事件数据写入到指定的日志文件
ActiveScriptEventConsumer: 用来执行VBScript/JScript程序
NTEventLogEventConsumer:创建一个包含事件数据的日志入口点
SMTPEventConsumer:将事件数据用邮件发送
CommandLineEventConsumer:执行一条命令
利用点
- ActiveScriptEventConsumer,允许执行任意脚本(支持- JScript和- VBScript引擎)
- CommandLineEventConsumer,允许执行任意命令
3.2 测试
使用以下查询进行测试:
Select * From __InstanceCreationEvent Where TargetInstance Isa "Win32_Process"
为了方便测试,此处使用 Powershell 的 Register-WMIEvent 安装触发器。

以上测试不符合实际需求。
3.3 Powershell 实例(命令执行)
下面的 PowerShell 代码来自一个叫 SEADADDY 的恶意软件的修改版,用来通过WMI做持久化的
| 1 | $EventFilterName = 'BotFilter11' | 
但是这里实测失败,就算使用C#去添加 CommandLineEventConsumer 也是失败的,但是 LogFileEventConsumer 可成功。
3.4 C# 实例(代码执行)
本示例执行的是 VBScript
使用SharpShooter生成 VBSceipt 类型的 payload。友情提示:一定要生成 64位的 payload。
| 1 | > python SharpShooter.py --stageless --dotnetver 2 --payload vbs --output implantvbs --rawscfile payload64.bin | 
示例代码:
| 1 | // WMI Event Subscription Peristence Demo | 
管理员权限运行生成的exe,演示 GIF

0x04 WMI后门检测及清除
4.1 Sysmon日志
略….
4.2 查看当前WMI Event
| 1 | 
 | 
4.3 清除后门
| 1 | 
 | 
0x05 参考
Persistence: “the continued or prolonged existence of something”: Part 3 – WMI Event Subscription
WMI Attacks
利用WMI构建无文件后门(基础篇)
 
        